/* ************************************************************************ */
/*                                                                          */
/*  Copyright (c)2005 Russell Weir | damonsbane _at_ gmail                  */
/*                                                                          */
/* This library is free software; you can redistribute it and/or            */
/* modify it under the terms of the GNU Lesser General Public               */
/* License as published by the Free Software Foundation; either             */
/* version 3.0 of the License, or (at your option) any later version.       */
/*                                                                          */
/* This library is distributed in the hope that it will be useful,          */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of           */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        */
/* Lesser General Public License or the LICENSE file for more details.      */
/*                                                                          */
/* ************************************************************************ */

package tzparser;
import tzparser.ZoneRule.ZoneRuleType;
import altdate.TimeSpecification;

class Zone {
	public var name(default,null)		: String;
	public var className(default,null) 	: String;
	public var packageName(default,null) 	: String;
	public var rules : Array<ZoneRule>;

	public function new(name : String) {
		this.name = name;
		var i : { classname: String, packagename: String } = Parser.zoneNameToClassVars(name);
		className = i.classname;
		packageName = i.packagename;

		rules = new Array();
	}

	public function addRule(rule:ZoneRule) {
		rules.push(rule);
	}

	public function finalize() {
		for(i in rules) {
			i.finalize();
		}
	}

	public function toString() : String {
		trace(here.methodName + " " + name);

		var data = StringTools.replace(ZoneClassText,'%%p%%',packageName);
		data = StringTools.replace(data,'%%c%%',className);
		data = StringTools.replace(data,'%%n%%',Parser.quotedString(name));
		data = StringTools.replace(data,'%%zcs%%',outzone());
		return data;
	}

	// This is out of zic.c outzone
	function outzone() {
		//var sb = new StringBuf();
		var cSet = new ZoneChangeSet();
		var starttime : altdate.JulianDay = null;
		var untiltime : altdate.JulianDay = null;
		for(i in 0...rules.length) {
			trace("Rule # "+i);
			var stdoff : TimeSpecification = new TimeSpecification();
			var usestart : Bool = (i > 0);
//trace(usestart);
			//var usestart : Bool = (i > 0) && rules[i-1].until < min_time;
			var useuntil : Bool = i < (rules.length -1);
			//if(useuntil && rules[i].until <= min_time)
			//	continue;
			var utcoff = rules[i].utcOffset;
			var startoff = rules[i].utcOffset;
			var zonename : String = null;

//trace(rules[i]);
			if(!rules[i].isChained()) {
				trace("> Non chained rule " + rules[i]);
				stdoff = rules[i].getStdOffset();
				//doabbr(startbuf, zp->z_format,(char *) NULL, stdoff != 0, FALSE);
				zonename = rules[i].format.getValue(stdoff);
				//type = addtype(oadd(zp->z_gmtoff, stdoff),
				//	startbuf, stdoff != 0, startttisstd,
				//	startttisgmt);
				if (usestart) {
					//addtt(starttime, type);
					cSet.add(new ZoneChange(zonename,starttime,utcoff,stdoff));
					usestart = false;
				}
				else { // if stdoff != 0 ?? huh
					//addtt(min_time, type);
					cSet.add(new ZoneChange(zonename,null,utcoff,stdoff));
				}
			}
			else { // ZoneRule is a chain
				for(y in Params.year_min...Params.year_max+1) {
					// if (useuntil && year > zp->z_untilrule.r_hiyear)
					if(useuntil && y > rules[i].until.year)
						break;

// 					/*
// 					** Mark which rules to do in the current year.
// 					** For those to do, calculate rpytime(rp, year);
// 					*/
// 					for (j = 0; j < zp->z_nrules; ++j) {
// 						rp = &zp->z_rules[j];
// 						eats(zp->z_filename, zp->z_linenum,
// 							rp->r_filename, rp->r_linenum);
// 						rp->r_todo = year >= rp->r_loyear &&
// 							year <= rp->r_hiyear &&
// 							yearistype(year, rp->r_yrtype);
// 						if (rp->r_todo)
// 							rp->r_temp = rpytime(rp, year);
// 					}
					var useRules = new Array<RuleForYear>();
					for(r in rules[i].chain) {
						if(r.isActiveForYear(y) == true)
							useRules.push(new RuleForYear(r,y));
					}
					// zic.c line 2093
					while(true) {
						//if(useuntil) hmm.. don't we need it even if not? MAXTIME
						untiltime = rules[i].until.toJulianDay(utcoff,stdoff);
						/*
						** Find the rule (of those to do, if any)
						** that takes effect earliest in the year.
						*/
						var lowest : RuleForYear = null;
						for(r in useRules) {
							var tjd = r.toJulianDay(utcoff, stdoff);
							if(lowest == null)
								lowest = r;
							else {
								if(tjd.value < lowest.julian.value)
									lowest = r;
							}
						}
						if(lowest == null)
							break;
						useRules.remove(lowest);
						if(useuntil && (lowest.julian.value >= untiltime.value))
							break;
						stdoff = lowest.save;
						// line 2144
						if(usestart) {
							if(lowest.julian.value == starttime.value)
								usestart = false;
						}
						if(usestart) {
							if(lowest.julian.value < starttime.value) {
								startoff = rules[i].utcOffset;
								zonename = rules[i].format.getValue(lowest.save, lowest.letter);
								continue;
							}
							if(zonename == null &&
								(startoff.value + stdoff.value == rules[i].utcOffset.value + stdoff.value)
								)
							{
								zonename = rules[i].format.getValue(lowest.save, lowest.letter);
							}
						}
						zonename = rules[i].format.getValue(lowest.save, lowest.letter);
						cSet.add(new ZoneChange(
								zonename,
								lowest.julian,
								rules[i].utcOffset,
								lowest.save
							));
					}// end while true, zic.c line 2175

				} // end for each valid year
			} // end of ZoneRule is a chain

			if(usestart) {
			}

			// line 2195
			if(useuntil)
				starttime = rules[i].until.toJulianDay(utcoff,stdoff);
		} // for(i in 0...rules.length)
		return cSet.toString();
	}

// %%p%% - package name
// %%n%% - timezone name - must be a Parser.quotedString
// %%c%% - Class name
// %%zcs%% - zone change set declarations
static var ZoneClassText : String = "
/* THIS FILE is automatically generated by tzparser, do not modify */

/* ************************************************************************ */
/*                                                                          */
/*  Copyright (c)2005 Russell Weir                                          */
/*                                                                          */
/* This library is free software; you can redistribute it and/or            */
/* modify it under the terms of the GNU Lesser General Public               */
/* License as published by the Free Software Foundation; either             */
/* version 3.0 of the License, or (at your option) any later version.       */
/*                                                                          */
/* This library is distributed in the hope that it will be useful,          */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of           */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        */
/* Lesser General Public License or the LICENSE file for more details.      */
/*                                                                          */
/* ************************************************************************ */

package %%p%%;
import tz.ChangeRecord;

class %%c%% extends tz.Zone {
	public static var abbrev : Array<String>;
	public static var changes : Array<ChangeRecord>;

	public function new() {
		super(%%n%%);
	}

	override public function getChanges() : Array<ChangeRecord> {
		return changes;
	}
	override public function getAbbrev() : Array<String> {
		return abbrev;
	}

	static function __init__() {
%%zcs%%
	}

} // class
";



}






